昨天我已經成功新增了「喜愛(愛心)」按鈕,點擊之後愛心會從空心 ♡ 變成實心 ♥,再點一次又會切回空心。這樣的互動效果已經不錯了,但仍然有一個問題:只要跳出頁面或重新整理,所有紀錄就會消失,愛心狀態會全部回到空心。
對於一個音樂專輯網站來說,這樣的體驗並不理想,因為使用者希望自己「喜愛」的歌曲能夠被記錄下來,甚至下次再打開網站時依然存在。今天的目標就是要解決這個問題。
// 1. 定義 localStorage 的 key,並讀取已喜愛的歌曲
const likedSongsKey = "likedSongs";
let likedSongs = JSON.parse(localStorage.getItem(likedSongsKey)) || [];
// 2. 取得網址參數 id
const urlParams = new URLSearchParams(window.location.search);
const id = urlParams.get("id");
// 3. 如果有對應的專輯就顯示
if (albums[id]) {
const album = albums[id];
document.getElementById("album-title").textContent = album.title;
document.getElementById("album-cover").src = album.cover;
document.getElementById("album-year").textContent = "Released:" + album.year;
const songList = document.getElementById("album-songs");
songList.innerHTML = ""; // 先清空列表
// 4. 顯示每首歌
album.songs.forEach((song, index) => {
const li = document.createElement("li");
if (typeof song === "string") {
li.textContent = `${index + 1}. ${song}`;
} else {
// 判斷這首歌是否已經被喜愛
const isLiked = likedSongs.includes(song.name);
li.innerHTML = `
<div class="song-item">
<span>${index + 1}. <a href="${song.url}" target="_blank">${song.name}</a></span>
<div class="action-btns">
<a href="lyrics.html?song=${album.title}-${song.name}" class="lyrics-btn">lyrics</a>
<button class="like-btn ${isLiked ? "liked" : ""}" data-song-name="${song.name}">
${isLiked ? "♥" : "♡"}
</button>
</div>
</div>
`;
}
songList.appendChild(li);
});
// 5. 隨機播放按鈕
const randomBtn = document.getElementById("random-play-btn");
randomBtn.addEventListener("click", () => {
const randomSong = album.songs[Math.floor(Math.random() * album.songs.length)];
const url = typeof randomSong === "string" ? "#" : randomSong.url;
if (url !== "#") window.open(url, "_blank");
else alert("這首歌沒有連結可以播放!");
});
// 6. 喜愛按鈕事件監聽
document.querySelectorAll(".like-btn").forEach(btn => {
btn.addEventListener("click", () => {
const songName = btn.dataset.songName;
likedSongs = JSON.parse(localStorage.getItem(likedSongsKey)) || [];
if (btn.textContent === "♡") {
// 點擊變紅心,加入 localStorage
btn.textContent = "♥";
btn.classList.add("liked");
if (!likedSongs.includes(songName)) likedSongs.push(songName);
} else {
// 再點一次變空心,從 localStorage 移除
btn.textContent = "♡";
btn.classList.remove("liked");
likedSongs = likedSongs.filter(name => name !== songName);
}
localStorage.setItem(likedSongsKey, JSON.stringify(likedSongs));
});
});
}
步驟解析
localStorage
key:likedSongs
來儲存所有被喜愛的歌曲名稱。讀取 URL 參數
URLSearchParams
取得專輯 id,確定要渲染哪一張專輯的歌曲清單。顯示專輯資訊
建立歌曲清單
<li>
元素。likedSongs
陣列裡,如果有就直接顯示成實心愛心 ♥。隨機播放按鈕
愛心按鈕點擊事件
這次最大的收穫是學會了如何利用 localStorage 來保存使用者狀態。其實這個技巧非常常見,不只是在音樂網站,像是購物車、瀏覽紀錄、偏好設定都會用到。
原本只是單純的按鈕切換效果,但加上 localStorage 之後,整個功能變得「有記憶」,就像網站真的認得我一樣。對使用者來說,體驗直接提升了一個層級。
下一篇文會再詳細解釋什麼是 localStorage